using System.Collections.Generic;
using System;

namespace Commons.Geom
{
	[Serializable]
	public class Shape
	{
		public List<Rectangle> Rectangles { get; protected set; }

		public Shape()
			: this (new List<Rectangle>())
		{
		}

		public Shape(Rectangle rectangle)
			: this ()
		{
			Rectangles.Add(rectangle);
		}

		public Shape(List<Rectangle> rectangles)
		{
			this.Rectangles = rectangles;
		}

		public bool Contains(int x, int y)
		{
			foreach (Rectangle rectangle in Rectangles)
			{
				if (rectangle.Contains(x, y))
				{
					return true;
				}
			}

			return false;
		}

		public bool Contains(Rectangle r)
		{
			for (int i = r.Left; i <= r.Right; i++)
			{
				for (int j = r.Bottom; j <= r.Top; j++)
				{
					if (!Contains(i, j))
					{
						return false;
					}
				}
			}

			return true;
		}

		public bool Intersects(Shape shape)
		{
			foreach (Rectangle r1 in Rectangles)
			{
				foreach (Rectangle r2 in shape.Rectangles)
				{
					if (r1.Intersects(r2))
					{
						return true;
					}
				}
			}

			return false;
		}

		public bool AdjacentTo(Rectangle rectangle)
		{
			foreach (Rectangle r in Rectangles)
			{
				if (r.AdjacentTo(rectangle))
				{
					return true;
				}
			}

			return false;
		}

		public bool AdjacentTo(Shape shape)
		{
			foreach (Rectangle rectangle in shape.Rectangles)
			{
				if (AdjacentTo(rectangle))
				{
					return true;
				}
			}

			return false;
		}

		public Rectangle Bounds
		{
			get
			{
				if (Rectangles.Count == 0)
				{
					return null;
				}

				int left = int.MaxValue;
				int top = int.MaxValue;
				int right = int.MinValue;
				int bottom = int.MinValue;

				foreach (Rectangle r in Rectangles)
				{
					if (r.Left < left)
					{
						left = r.Left;
					}
					if (r.Top < top)
					{
						top = r.Top;
					}
					if (r.Right > right)
					{
						right = r.Right;
					}
					if (r.Bottom > bottom)
					{
						bottom = r.Bottom;
					}
				}

				return new Rectangle(left, top, right - left, top - bottom);
			}
		}
	}
}

